/*
package test.groovy

import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.ast.CodeVisitorSupport
import org.codehaus.groovy.ast.ModuleNode
import org.codehaus.groovy.ast.expr.ArgumentListExpression
import org.codehaus.groovy.ast.expr.ConstantExpression
import org.codehaus.groovy.ast.expr.GStringExpression
import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer
import org.codehaus.groovy.control.customizers.SecureASTCustomizer
import org.codehaus.groovy.transform.ASTTransformation
import org.codehaus.groovy.transform.GroovyASTTransformation

@Slf4j
@GroovyASTTransformation
public class StatementTransformation implements ASTTransformation {
    private def transformations = ['use': 'using']

    @Override
    void visit(ASTNode[] nodes, SourceUnit source) {
        log.info("Source name = ${source.name}")
        ModuleNode ast = source.ast
        def blockStatement = ast.statementBlock

        blockStatement.visit(new CodeVisitorSupport() {
            void visitConstantExpression(ConstantExpression ce) {
                def name = ce.value
                if (transformations.containsKey(name)) {
                    def newName = transformations[name]
                    log.debug("Transform Name => $name -> $newName")
                    ce.value = newName
                } else {
                    log.debug("Skip Name => $name")
                }
            }

            public void visitArgumentlistExpression(ArgumentListExpression ale) {
                log.debug("Arg List $ale.expressions")
                def expressions = ale.expressions
                expressions.eachWithIndex {
                    expr, idx ->
                    if (expr.getClass() == GStringExpression) {
                        log.debug("Transform GString => String ($expr.text)")
                        expressions[idx] = new ConstantExpression(expr.text)
                    }
                }
                log.debug("Transformed Arg List $ale.expressions")
                super.visitArgumentlistExpression(ale)
            }
        })
    }
}


@Slf4j
public class Reader {
    private def createNewShell() {
        def secureCustomizer = new SecureASTCustomizer()
        secureCustomizer.with {
            methodDefinitionAllowed = false // user will not be able to define methods
            importsWhitelist = [] // empty whitelist means imports are disallowed
            staticImportsWhitelist = [] // same for static imports
            staticStarImportsWhitelist = []
        }

        def astCustomizer =
                new ASTTransformationCustomizer(new StatementTransformation())
        def config = new CompilerConfiguration()
        config.addCompilationCustomizers(secureCustomizer,
                astCustomizer)
        new GroovyShell(config)
    }

    public Tree read(final List<File> deltas) {
        def parser = new Parser()
        deltas.each { delta ->
            def deltaName = delta.name
            def dslCode = """{-> $delta.text}"""
            //shell evaluates once, hence create new each time
            def shell = createNewShell()
            def deltaObject = shell.evaluate(dslCode, deltaName)
            try {
                parser.parse(deltaObject)
            } catch (Throwable t) {
                throw new InvalidGrammar("$deltaName --> ${t.message}")
            }
            shell = null
        }
        parser.ast()
    }
}


@Slf4j
class Parser {
    private Tree tree = new Tree()
    private def dbContext

    @CompileStatic
    def getProperty(String name) {
        log.debug("property name is: $name")
        if (name == 'db') {
            return dbContext
        }
        tree.using(name)
    }

    def using(db) {
        log.info "Setting db context to ${db.toString()}"
        dbContext = db
    }

    public Tree parse(Closure closure) {
        def cloned = closure.clone()
        cloned.delegate = this
        cloned.resolveStrategy = Closure.DELEGATE_FIRST
        cloned()
        tree
    }

    def ast() {
        tree
    }
}
*/
